﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Common.Utilities;
using WindowsUserControl.Controls;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsUserControl.UIUpdateWrapper
{
    /// <summary>
    /// 
    /// </summary>
    public class TreeGridViewUpdator
    {
        TreeGridView _TreeGV;
        List<string> _ColHeaders;
        Dictionary<string, string> _MasterFieldColHeaderMappings;
        Dictionary<string, string> _DetailFieldColHeaderMappings;
        DataTable _DetailTable;
        DataTable _MasterTable;
        string _ParentKey;
        string _ChildKey;
        private Dictionary<int, List<int>> _Pk_Fk_Mappings;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="treeGV"></param>
        /// <param name="dtMaster"></param>
        /// <param name="dtDetail"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="colHeaders"></param>
        public TreeGridViewUpdator( TreeGridView treeGV,
            DataTable dtMaster, DataTable dtDetail,
            string pk, string fk, List<string> colHeaders)
        {
            this._TreeGV = treeGV;
            this._DetailTable = dtDetail;
            this._MasterTable = dtMaster;
            this._ParentKey = pk;
            this._ChildKey = fk;
            this._ColHeaders = colHeaders;
            this._MasterFieldColHeaderMappings = new Dictionary<string, string>();
            this._DetailFieldColHeaderMappings = new Dictionary<string, string>();
            foreach (DataColumn col in dtMaster.Columns)
            {
                if (this._ColHeaders.Contains(col.ColumnName))
                {
                    this._MasterFieldColHeaderMappings.Add(col.ColumnName, col.ColumnName);
                }
            }
            foreach (DataColumn col in dtDetail.Columns)
            {
                if (this._ColHeaders.Contains(col.ColumnName))
                {
                    this._DetailFieldColHeaderMappings.Add(col.ColumnName, col.ColumnName);
                }
            }

            this._Pk_Fk_Mappings = null;
            this._TreeGV.Invoke(new MethodInvoker(this.PopulateTableContents));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="treeGV"></param>
        /// <param name="dtMaster"></param>
        /// <param name="dtDetail"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="detailID_MasterID_Mappings"></param>
        /// <param name="colHeaders"></param>
        public TreeGridViewUpdator(
            TreeGridView treeGV, 
            DataTable dtMaster, 
            DataTable dtDetail, 
            string pk, 
            string fk,
            Dictionary<int, int> detailID_MasterID_Mappings,
            List<string> colHeaders)
        {
            this._TreeGV = treeGV;
            this._DetailTable = dtDetail;
            this._MasterTable = dtMaster;
            this._ParentKey = pk;
            this._ChildKey = fk;
            this._Pk_Fk_Mappings=new Dictionary<int, List<int>>();
            foreach(int fkVal in detailID_MasterID_Mappings.Keys)
            {
                int pkVal = detailID_MasterID_Mappings[fkVal];
                if(this._Pk_Fk_Mappings.ContainsKey(pkVal))
                {
                    List<int> fkVals = this._Pk_Fk_Mappings[pkVal];
                    fkVals.Add(fkVal);
                    this._Pk_Fk_Mappings[pkVal] = fkVals;
                }
                else
                {
                    List<int> fkVals=new List<int>();
                    fkVals.Add(fkVal);
                    this._Pk_Fk_Mappings.Add(pkVal,fkVals);
                }
            }
            this._ColHeaders = colHeaders;
            this._MasterFieldColHeaderMappings = new Dictionary<string, string>();
            this._DetailFieldColHeaderMappings = new Dictionary<string, string>();
            foreach (DataColumn col in dtMaster.Columns)
            {
                if (this._ColHeaders.Contains(col.ColumnName))
                {
                    this._MasterFieldColHeaderMappings.Add(col.ColumnName, col.ColumnName);
                }
            }
            foreach (DataColumn col in dtDetail.Columns)
            {
                if (this._ColHeaders.Contains(col.ColumnName))
                {
                    this._DetailFieldColHeaderMappings.Add(col.ColumnName, col.ColumnName);
                }
            }

            this._TreeGV.Invoke(new MethodInvoker(this.PopulateTableContents));
        }

        private void PopulateTableContents()
        {
            this._TreeGV.Nodes.Clear();
            this._TreeGV.Columns.Clear();
            foreach (string colName in this._ColHeaders)
            {
                DataGridViewColumn col = new DataGridViewColumn();
                if (colName == this._ParentKey)
                {
                    col.CellTemplate = new TreeGridCell();
                }
                else
                {
                    col.CellTemplate = new DataGridViewTextBoxCell();
                }
                col.HeaderText = colName;
                this._TreeGV.Columns.Add(col);
            }

            Font boldFont = new Font(this._TreeGV.DefaultCellStyle.Font, FontStyle.Bold);

            for (int i = 0; i < this._MasterTable.Rows.Count; i++)
            {
                List<object> parentRowValues = new List<object>();
                foreach (string colHeader in this._ColHeaders)
                {
                    if (this._MasterFieldColHeaderMappings.ContainsKey(colHeader))
                    {
                        parentRowValues.Add(this._MasterTable.Rows[i][colHeader]);
                    }
                    else
                    {
                        parentRowValues.Add(DBNull.Value);
                    }
                }
                TreeGridNode parentNode = this._TreeGV.Nodes.Add(parentRowValues.ToArray());
                parentNode.DefaultCellStyle.Font = boldFont;
                parentNode.DefaultCellStyle.BackColor = Color.Gainsboro;

                int keyValue = (int)this._MasterTable.Rows[i][this._ParentKey];
                DataRow[] drDetails = null;
                if (this._Pk_Fk_Mappings == null || this._Pk_Fk_Mappings.Count == 0)
                {
                    drDetails = this._DetailTable.Select(string.Format("{0}={1}", this._ChildKey, keyValue));
                }
                else if(this._Pk_Fk_Mappings.ContainsKey(keyValue))
                {
                    List<int> detailIDs = this._Pk_Fk_Mappings[keyValue];
                    drDetails = this._DetailTable.Select(
                        string.Format("{0} in ({1})",
                                      this._ChildKey,
                                      IntUtil.ToString(detailIDs.ToArray())));
                }
                if (drDetails != null && drDetails.Length > 0)
                {
                    for (int k = 0; k < drDetails.Length; k++)
                    {
                        List<object> childRowValues = new List<object>();
                        foreach (string colHeader in this._ColHeaders)
                        {
                            if (this._DetailFieldColHeaderMappings.ContainsKey(colHeader))
                            {
                                childRowValues.Add(drDetails[k][colHeader]);
                            }
                            else
                            {
                                childRowValues.Add(DBNull.Value);
                            }
                        }
                        parentNode.Nodes.Add(childRowValues.ToArray());
                    }
                }
            }
            
        }
    }
}
